import React, { useEffect, useState } from "react";
import { makeStyles } from "@material-ui/core/styles";
import { AppBar, Button, Collapse, Container, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, FilledInput, FormControl, FormControlLabel, IconButton, Input, InputAdornment, InputLabel, Paper, Radio, RadioGroup, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, TextField, Toolbar, Typography } from "@material-ui/core";
import DashboardIcon from "@material-ui/icons/Dashboard";
import Pagination from '@material-ui/lab/Pagination';
import { Alert } from "@material-ui/lab";
import CloseIcon from '@material-ui/icons/Close'
import DeleteIcon from '@material-ui/icons/Delete'

const useStyles = makeStyles((theme) => ({
  root: {
    flexGrow: 1,
  },
  icon: {
    marginRight: theme.spacing(2),
  },
  appBar: {
    backgroundColor: theme.palette.background.paper,
  },
  title: {
    flexGrow: 1,
  },
  container: {
    paddingTop: 16,
    paddingBottom: 16,
  },
  paper: {
    padding: 16,
    marginBottom: 16
  },
  button: {
    marginRight: theme.spacing(2),
  },
  table: {

  }
}));

const logout = () => {
  fetch('/logout', {
    method: 'post'
  }).then(() => {
    if (localStorage.getItem('type') === null || localStorage.getItem('type') === '') {
      window.location.href = '/login/text';
    } else {
      window.location.href = '/login/' + localStorage.getItem('type');
    }
  });
}

export default function HeadBar() {
  const classes = useStyles();
  const [page, setPage] = useState(0);
  const [totalPage, setTotalPage] = useState(1);
  const [list, setList] = useState([]);
  const [addUserDialogOpen, setAddUserDialogOpen] = useState(false)
  const [clearAllDialogOpen, setClearAllDialogOpen] = useState(false)
  const [importDialogOpen, setImportDialogOpen] = useState(false)
  const [importFmt, setImportFmt] = useState('json')

  // 0：用户列表  1：最近访问列表
  const [dataId, setDataId] = useState('0');

  const handlePageChange = (e, v) => {
    setPage(v)
  }

  const handleDataIdChange = (e, v) => {
    setPage(1)
    setDataId(v)
  }

  const fetchStatisticsData = () => {
    if (page > 0) {
      fetch('/statistics/list?page=' + page)
        .then(res => res.json()).then(data => {
          setTotalPage(data['totalPages'])
          setList(data['list'])
        })
    }
  }

  const fetchAccessRecordsData = () => {
    if (page > 0) {
      fetch('/records/list?page=' + page)
        .then(res => res.json()).then(data => {
          setTotalPage(data['totalPages'])
          setList(data['list'])
        })
    }
  }

  const exportData = (fmt) => {
    const url = '/api/admin/export?data=' + (dataId === '0' ? 'users' : 'records') + '&format=' + fmt
    window.location.href = url
  }

  useEffect(() => {
    if (dataId === '0') {
      fetchStatisticsData()
    } else {
      fetchAccessRecordsData()
    }
  }, [page, dataId])

  if (page <= 0) {
    setPage(1)
  }

  return (
    <div className={classes.root}>
      <AppBar position="static" className={classes.appBar}>
        <Toolbar>
          <DashboardIcon className={classes.icon} color="primary" />
          <Typography variant="h6" className={classes.title} color="textPrimary">管理面板</Typography>
          <Button color="inherit" variant="outlined" onClick={logout} color="textPrimary">注销</Button>
        </Toolbar>
      </AppBar>
      <Container className={classes.container}>
        <Paper variant="outlined" className={classes.paper}>
          <Typography variant="h5" gutterBottom>数据操作</Typography>
          <div>
            <RadioGroup name="dataId" value={dataId} onChange={handleDataIdChange}>
              <FormControlLabel value="0" label="学生列表" control={<Radio />}/>
              <FormControlLabel value="1" label="最近请求列表" control={<Radio />}/>
            </RadioGroup>
          </div>
          {dataId === '0' ? (
            <div style={{marginTop: 16, marginBottom: 16}}>
              <Button
                className={classes.button}
                type="button"
                variant="outlined"
                onClick={() => setAddUserDialogOpen(true)}>添加学生</Button>
              <Button
                className={classes.button}
                type="button"
                variant="outlined"
                onClick={() => {
                  setImportFmt('csv')
                  setImportDialogOpen(true)
                }}>导入学生数据（CSV）</Button>
              <Button
                className={classes.button}
                type="button"
                variant="outlined"
                onClick={() => {
                  setImportFmt('json')
                  setImportDialogOpen(true)
                }}>导入学生数据（JSON）</Button>
            </div>
          ) : (<></>)}
          <div>
            <Button 
              className={classes.button}
              type="button"
              variant="outlined"
              onClick={() => exportData('csv')}>导出数据（CSV）</Button>
            <Button 
              className={classes.button}
              type="button"
              variant="outlined"
              onClick={() => exportData('json')}>导出数据（JSON）</Button>
            <Button 
              className={classes.button}
              color="secondary"
              type="button"
              variant="contained"
              onClick={() => setClearAllDialogOpen(true)}>清空数据</Button>
          </div>
        </Paper>
        <TableContainer component={Paper}>
          <Table>
            <TableHead>
              {dataId === '0' ? (
                <TableRow>
                  <TableCell>用户ID</TableCell>
                  <TableCell>用户名</TableCell>
                  <TableCell>登录请求次数</TableCell>
                  <TableCell>成功登录次数</TableCell>
                  <TableCell>成功率</TableCell>
                </TableRow>
              ) : (
                <TableRow>
                  <TableCell>记录ID</TableCell>
                  <TableCell>请求说明</TableCell>
                  <TableCell>请求时间</TableCell>
                  <TableCell>验证码类型</TableCell>
                  <TableCell>用户名</TableCell>
                </TableRow>
              )}
            </TableHead>
            <TableBody>
              {list ? list.map(item => (
                dataId === '0' ? (
                  <TableRow hover key={item.userId}>
                    <TableCell>{item.userId}</TableCell>
                    <TableCell>{item.username}</TableCell>
                    <TableCell>{item.access}</TableCell>
                    <TableCell>{item.success}</TableCell>
                    <TableCell>{item.successRate}</TableCell>
                  </TableRow>
                ) : (
                  <TableRow hover key={item.id}>
                    <TableCell>{item.id}</TableCell>
                    <TableCell color={item.access === 0 ? "textSecondary" : "textPrimary"}>
                      {item.access === 0 ? '登录请求' : '登录成功'}</TableCell>
                    <TableCell>{item.addTime}</TableCell>
                    <TableCell>{item.type}</TableCell>
                    <TableCell>{item.username}</TableCell>
                  </TableRow>
                )
              )) : <></>}
            </TableBody>
          </Table>
        </TableContainer>
        <div style={{marginTop: 16}}>
          <Pagination style={{float: 'right'}} count={totalPage} page={page} onChange={handlePageChange} />
          <div style={{clear: 'both'}}></div>
        </div>
      </Container>
      {/* 添加用户对话框 */}
      <AddUserDialog state={[addUserDialogOpen, setAddUserDialogOpen]} setPage={setPage} />
      {/* 清空数据对话框 */}
      <ClearAllDialog state={[clearAllDialogOpen, setClearAllDialogOpen]} dataId={dataId} setPage={setPage} />
      <ImportDialog state={[importDialogOpen, setImportDialogOpen]} fmt={importFmt} setPage={setPage} />
    </div>
  );
}

function AddUserDialog(props) {
  const [open, setOpen] = props.state
  const [loading, setLoading] = useState(false)
  const [username, setUsername] = useState('')
  const [password, setPassword] = useState('')
  const [toast, setToast] = useState('')
  const [toastVariant, setToastVariant] = useState('success')

  const handleClose = () => {
    setOpen(false);
  };

  const handleSubmit = () => {
    setLoading(true)
    fetch('/api/admin/user', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
      },
      body: new URLSearchParams({
        'username': username,
        'password': password
      })
    }).then(resp => {
      setLoading(false)
      try {
        return resp.json()
      } catch (e) {
        return {'code': -1, 'message': e}
      }
    }).then(data => {
      if (data.code !== 0) {
        setToastVariant('error')
        setToast(data.message)
      } else {
        // success
        setUsername('')
        setPassword('')
        setToastVariant('success')
        setToast('添加成功')
        props.setPage(0)
      }
    }).catch(e => {
      setToastVariant('error')
      setToast(e + '')
    })
  }

  return (
    <Dialog open={open} onClose={handleClose} disableBackdropClick disableEscapeKeyDown aria-labelledby="form-dialog-title">
      <DialogTitle id="form-dialog-title">添加学生</DialogTitle>
      <DialogContent>
        <DialogContentText>
          请输入学生的用户名和密码，并点击提交。
        </DialogContentText>
        <TextField
          autoFocus
          margin="dense"
          id="username"
          label="用户名"
          type="text"
          variant="outlined"
          value={username}
          onChange={(e) => setUsername(e.target.value.substr(0, 20))}
          fullWidth
          disabled={loading}
        />
        <TextField
          autoFocus
          margin="dense"
          id="password"
          label="密码"
          type="password"
          variant="outlined"
          value={password}
          onChange={(e) => setPassword(e.target.value.substr(0, 20))}
          fullWidth
          disabled={loading}
        />
        <Collapse in={toast !== ''}>
          <Alert
            severity={toastVariant}
            action={
              <IconButton
                aria-label="close"
                color="inherit"
                size="small"
                onClick={() => {
                  setToast('');
                }}
              >
                <CloseIcon fontSize="inherit" />
              </IconButton>
            }>
            {toast}
          </Alert>
        </Collapse>
      </DialogContent>
      <DialogActions>
        <Button onClick={handleClose} color="primary" 
          disabled={loading}>
          取消
        </Button>
        <Button onClick={handleSubmit} color="primary" 
          disabled={loading}>
          {loading ? '正在提交' : '提交'}
        </Button>
      </DialogActions>
    </Dialog>
  );
}

function ClearAllDialog(props) {
  const [open, setOpen] = props.state
  const [loading, setLoading] = useState(false)

  const text = () => {
    if (props.dataId === '0') {
      return '该操作将会清空所有学生数据，且操作不可逆。建议在数据导出后清空。'
    } else {
      return '该操作将会清空所有请求数据，且操作不可逆。建议在数据导出后清空。'
    }
  }

  const handleClose = () => {
    setOpen(false);
  };

  const clearAll = () => {
    setLoading(true)
    let url = props.dataId === '0' ? '/api/admin/user' : '/api/admin/statistics'
    fetch(url, {
      method: 'DELETE'
    }).then(resp => {
      setLoading(false)
      handleClose()
      try {
        return resp.json()
      } catch (e) {
        return {'code': -1, 'message': e}
      }
    }).finally(() => {
      setLoading(false)
      props.setPage(0)
    })
  }

  return (
    <Dialog open={open} onClose={handleClose} aria-labelledby="form-dialog-title">
      <DialogTitle id="form-dialog-title">清空数据</DialogTitle>
      <DialogContent>
        <DialogContentText>
          {text()}
        </DialogContentText>
      </DialogContent>
      <DialogActions>
        <Button onClick={handleClose} color="primary" 
          disabled={loading}>
          取消
        </Button>
        <Button onClick={clearAll} color="secondary" variant="contained" 
          disabled={loading}>
          {loading ? '正在操作' : '清空'}
        </Button>
      </DialogActions>
    </Dialog>
  )
}

function ImportDialog(props) {
  const [open, setOpen] = props.state
  const [loading, setLoading] = useState(false)
  const [content, setContent] = useState('')
  const [toast, setToast] = useState('')
  const [toastVariant, setToastVariant] = useState('success')
  const [localFile, setLocalFile] = useState(undefined)
  const fmt = props.fmt
  
  const handleClose = () => {
    setOpen(false);
  };
  
  const handleFileChoose = () => {
    document.getElementById('btn-import-file-choose').click()
  }

  const handleFileInputChange = (e) => {
    const file = document.getElementById('btn-import-file-choose').files[0]
    if (file) {
      // const reader = new FileReader()
      // reader.readAsText(file, 'UTF-8')
      // reader.onload = (e) => {
      //   setLocalFile(e.target.result)
      // }
      setLocalFile(file)
    }
  }

  const handleSubmit = () => {
    setLoading(true)

    const formData = new FormData()
    if (localFile) {
      formData.append('file', localFile)
    } else {
      formData.append('content', content)
    }
    formData.append('data', 'users')
    formData.append('format', fmt)

    fetch('/api/admin/import', {
      method: 'POST',
      body: formData
    }).then(resp => {
      setLoading(false)
      try {
        return resp.json()
      } catch (e) {
        return {'code': -1, 'message': e}
      }
    }).then(data => {
      if (data.code !== 0) {
        setToastVariant('error')
        setToast(data.message)
      } else {
        // success
        setContent('')
        setLocalFile(undefined)
        document.getElementById('btn-import-file-choose').value = ''
        setToastVariant('success')
        setToast('导入成功')
        props.setPage(0)
      }
    }).catch(e => {
      setToastVariant('error')
      setToast(e + '')
    })
  };

  return (
    <Dialog fullWidth open={open} onClose={handleClose} disableBackdropClick 
    disableEscapeKeyDown scroll="paper" aria-labelledby="form-dialog-title">
      <DialogTitle id="form-dialog-title">导入数据</DialogTitle>
      <DialogContent>
        {localFile === undefined ? (
          <TextField
            autoFocus
            margin="dense"
            id="content"
            label={fmt.toUpperCase() + '内容'}
            type="text"
            variant="filled"
            value={content}
            onChange={(e) => setContent(e.target.value)}
            fullWidth
            multiline
            disabled={loading}
          />
        ) : (
          <FormControl fullWidth>
            <InputLabel htmlFor="import-file-text" style={{margin: 8}}>选取文件</InputLabel>
            <FilledInput
              id="import-file-text"
              fullWidth
              endAdornment={
                <InputAdornment position="end">
                  <IconButton edge="end" onClick={() => {
                    setLocalFile(undefined)
                    document.getElementById('btn-import-file-choose').value = ''
                  }}>
                    <DeleteIcon />
                  </IconButton>
                </InputAdornment>
              }
              value={localFile.name}
              onChange={() => {}}
              disabled
            >
            </FilledInput>
          </FormControl>
        )}
        <Collapse in={toast !== ''}>
          <Alert
            severity={toastVariant}
            action={
              <IconButton
                aria-label="close"
                color="inherit"
                size="small"
                onClick={() => {
                  setToast('');
                }}
              >
                <CloseIcon fontSize="inherit" />
              </IconButton>
            }>
            {toast}
          </Alert>
        </Collapse>
      </DialogContent>
      <DialogActions>
        <Button onClick={handleClose} color="primary" 
          disabled={loading}>
          取消
        </Button>
        <Button onClick={() => setContent('')} color="primary" 
          disabled={loading}>
          清空
        </Button>
        <Input type="file" style={{display: 'none'}} id="btn-import-file-choose" onChange={handleFileInputChange}>选取文件</Input>
        <Button onClick={handleFileChoose} color="primary"
          disabled={loading}>
          选取文件
        </Button>
        <Button onClick={handleSubmit} color="secondary" 
          disabled={loading}>
          {loading ? '正在提交' : '提交'}
        </Button>
      </DialogActions>
    </Dialog>
  );
}